package com.ceair.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ceair.entity.SysRole;
import com.ceair.entity.request.role.*;
import com.ceair.entity.result.PageResult;
import com.ceair.entity.result.Result;
import com.ceair.entity.vo.role.RoleAuthorityVO;
import com.ceair.entity.vo.role.SysRoleVO;
import com.ceair.exception.BusinessException;
import com.ceair.service.ISysRoleService;
import com.ceair.utils.structMapper.SysRoleStructMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author wangbaohai
 * @ClassName SysRoleController
 * @description: 角色接口
 * @date 2025年02月26日
 * @version: 1.0.0
 */
@RestController
@RequestMapping("/api/v1/role")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "角色管理", description = "角色管理相关接口")
public class SysRoleController {

    private final ISysRoleService sysRoleService;

    /**
     * 处理角色信息的分页查询请求
     *
     * @param queryRoleReq 包含分页查询条件的角色信息请求对象
     * @return 返回一个PageResult对象，其中包含角色信息的视图对象列表和总记录数
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/role/page')")
    @Parameter(name = "queryRoleReq", description = "角色信息查询请求对象", required = true)
    @Operation(summary = "分页查询角色信息")
    @PostMapping("/page")
    public PageResult<List<SysRoleVO>> queryRoleWithPage(@RequestBody QueryRoleReq queryRoleReq) {
        // 分页查询
        Page<SysRole> page = sysRoleService.queryRoleWithPage(queryRoleReq);

        // 将查询结果中的记录转换为视图对象（VO）列表
        List<SysRoleVO> list =
                Optional.ofNullable(page.getRecords()).orElse(Collections.emptyList()).parallelStream().map(record -> {
                            try {
                                // 使用映射器将实体对象转换为视图对象
                                return SysRoleStructMapper.INSTANCE.toVO(record);
                            } catch (Exception e) {
                                // 记录转换失败的错误信息
                                log.error("转换角色信息失败 具体原因为 : {}", e.getMessage());
                                return null;
                            }
                        }).filter(Objects::nonNull)
                        .toList();

        // 返回包含转换后列表和列表大小的PageResult对象
        return PageResult.success(list, page.getTotal());
    }

    /**
     * 保存角色信息接口
     * 该方法通过POST请求接收角色相关数据，将数据传递给系统角色服务进行保存
     * 主要用于创建或更新角色信息
     *
     * @param roleInOrUpReq 角色请求对象，包含需要保存或更新的角色信息
     * @return 返回保存结果，封装在Result对象中
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/role/save')")
    @Parameter(name = "roleInOrUpReq", description = "角色信息新增或更新请求对象", required = true)
    @Operation(summary = "新增或更新角色信息")
    @PostMapping("/save")
    public Result<SysRoleVO> save(@RequestBody RoleInOrUpReq roleInOrUpReq) {
        // 初始化
        SysRoleVO sysRoleVO;

        // 调用服务层方法保存权限信息，并将结果封装为成功响应返回
        try {
            sysRoleVO = sysRoleService.save(roleInOrUpReq);
        } catch (Exception e) {
            // 处理异常，记录错误信息
            log.error("新增或更新权限失败 具体原因为 : {}", e.getMessage());
            return Result.error("新增或更新权限失败 具体原因为 : " + e.getMessage());
        }
        return Result.success(sysRoleVO);
    }

    /**
     * 查询角色权限的接口方法
     *
     * @param queryRoleAuthorityReq 角色权限查询请求对象，包含查询所需的参数，如角色ID
     * @return 返回一个Result对象，其中包含角色权限的列表
     *
     * 此方法通过角色ID查询该角色所拥有的权限列表，并将结果封装在Result对象中返回
     * 使用@PostMapping注解指定该方法为POST请求处理方法，路径为"/queryRoleAuthority"
     * 使用@Parameter和@Operation注解提供API文档信息，描述参数和操作的细节
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/role/queryRoleAuthority')")
    @Parameter(name = "queryRoleAuthorityReq", description = "角色权限查询请求对象", required = true)
    @Operation(summary = "查询角色权限")
    @PostMapping("/queryRoleAuthority")
    public Result<List<RoleAuthorityVO>> queryRoleAuthority(@RequestBody QueryRoleAuthorityReq queryRoleAuthorityReq) {
        // 调用sysRoleService的queryRoleAuthority方法，传入角色ID，获取角色权限列表
        // 将查询结果封装为Result对象并返回
        return Result.success(sysRoleService.queryRoleAuthority(queryRoleAuthorityReq.getId()));
    }

    /**
     * 更新角色权限的接口方法
     *
     * @param updateRoleAuthorityReq 角色权限更新请求对象，包含需要更新的角色权限信息
     * @return 返回更新操作的结果，包括是否成功
     *
     * 此方法通过接收一个角色权限更新请求对象来更新系统中的角色权限配置
     * 它使用HTTP POST请求方式，表明这是一个修改操作
     *
     * 注解说明：
     * @Parameter 用于描述参数的相关信息，这里指明了参数是必需的，并且解释了参数的用途
     * @Operation 用于描述方法的操作摘要，这里简单明了地说明了方法的功能是更新角色权限
     * @PostMapping 指定这是一个处理POST请求的方法，路径为"/updateRoleAuthority"
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/role/updateRoleAuthority')")
    @Parameter(name = "updateRoleAuthorityReq", description = "角色权限更新请求对象", required = true)
    @Operation(summary = "更新角色权限")
    @PostMapping("/updateRoleAuthority")
    public Result<Boolean> updateRoleAuthority(@RequestBody UpdateRoleAuthorityReq updateRoleAuthorityReq) {
        // 调用sysRoleService的updateRoleAuthority方法，传入角色权限更新请求对象，返回更新操作的结果
        Boolean result;
        try {
            result = sysRoleService.updateRoleAuthority(updateRoleAuthorityReq);
        } catch (BusinessException e) {
            // 处理异常，记录错误信息
            log.error("更新角色权限失败 具体原因为 : {}", e.getMessage());
            return Result.error(e.getMessage());
        }
        return Result.success(result);
    }

    /**
     * 删除角色的接口方法
     *
     * @param deleteRoleReq 角色删除请求对象，包含需要删除的角色信息
     * @return 返回删除操作的结果，包括是否删除成功
     */
    @PreAuthorize("hasAnyAuthority('/api/v1/role/delete')")
    @Parameter(name = "deleteRoleReq", description = "角色删除请求对象", required = true)
    @Operation(summary = "删除角色")
    @PostMapping("/delete")
    public Result<Boolean> delete(@RequestBody DeleteRoleReq deleteRoleReq) {
        // 调用sysRoleService的delete方法，传入角色删除请求对象，返回删除操作的结果
        Boolean result;
        try {
            result = sysRoleService.delete(deleteRoleReq);
        } catch (BusinessException e) {
            // 处理异常，记录错误信息
            log.error("删除角色失败 具体原因为 : {}", e.getMessage());
            return Result.error("删除角色失败,失败原因：" + e.getMessage());
        }
        return Result.success(result);
    }

}
